package com.taptech.doufu.manager;

import android.content.SharedPreferences;
import android.text.TextUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.taptech.doufu.app.WeMediaApplication;
import com.taptech.doufu.constant.Constant;
import com.taptech.doufu.db.noveledit.NovelEditDBUtil;
import com.taptech.doufu.event.EventBusRefreshData;
import com.taptech.doufu.listener.PublicInterface;
import com.taptech.doufu.net.retrofit.api.ApiClient;
import com.taptech.doufu.net.retrofit.api.BaseSubscriber;
import com.taptech.doufu.net.retrofit.api.RxJavaHelper;
import com.taptech.doufu.bean.NovelChapterIDBean;
import com.taptech.doufu.bean.NovelChaptersGsonBean;
import com.taptech.doufu.bean.NovelEditModel;
import com.taptech.doufu.bean.NovelUploadBackupGsonBean;
import com.taptech.doufu.bean.base.ResponseBaseBean;
import com.taptech.doufu.services.personalcenter.AccountService;
import com.taptech.doufu.util.NetworkUtil;
import com.taptech.doufu.util.SharedPreferenceUtil;
import com.taptech.doufu.util.sp.DiaoBaoSharedPreferences;

import org.greenrobot.eventbus.EventBus;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

public class NovelEditManager {

    private static NovelEditManager editManager = new NovelEditManager();

    public static final int NOVEL_DRAFTS = 0;  //草稿
    public static final int NOVEL_SECTION = 1; //已发布
    public static final int NOVEL_CREATE = 2;  //新建
    NovelEditDBUtil dbUtil = new NovelEditDBUtil(WeMediaApplication.applicationContext);

    public static NovelEditManager getInstance() {
        return editManager;
    }

    public interface OnResult{
        void onSuccess();
        void onError(String msg);
    }

    /**
     * 上传单个草稿
     * @param model 数据
     * @param onResult 接口回调
     * @param isRepeat 是否是重复数据
     * @param isSaveByUser 是否通过用过点击保存
     */
    public void uploadData(final NovelEditModel model,
                           final OnResult onResult,
                           boolean isRepeat,
                           boolean isSaveByUser) {
        //存储到本地
        if (!isRepeat) {  //上传的数据不重复则需要先将数据保存到本地
            if ("-1".equals(model.getChapter_id())) {  //本地已经存在该数据，直接修改
                if (model.getId() > 0){
                    dbUtil.updateSingleData(model,model.getId());
                }else{
                    long id = dbUtil.insertSingleData(model);
                    model.setId(id);
                }
            }else{
                dbUtil.insertSingleData(model);
            }
            deleteByDBId(model.getTempDbId());
        }
        if (!isRepeat || isSaveByUser) {
            if ("-1".equals(model.getChapter_id())) {
                model.setFlag(NOVEL_CREATE);
                //上传到服务器
                ApiClient.getInstance().getService().uploadMySingleBackUp(formatData(model))
                        .map(new Func1<ResponseBaseBean, ResponseBaseBean>() {
                            @Override
                            public ResponseBaseBean call(ResponseBaseBean responseBaseBean) {
                                if (model.getId() > 0) {
                                    dbUtil.deleteById(model.getId());
                                }else{
                                    //删除本地数据
                                    dbUtil.deleteByChapterId(model.getNovel_id(),model.getChapter_id());
                                }
                                return responseBaseBean;
                            }
                        })
                        .compose(RxJavaHelper.<ResponseBaseBean>observeOnMainThread())
                        .subscribe(new BaseSubscriber<ResponseBaseBean>(){
                            @Override
                            public void onError(Throwable e) {
                                super.onError(e);
                                if (onResult != null) {
                                    onResult.onError("成功保存至本地");
                                }
                            }

                            @Override
                            public void onNext(ResponseBaseBean responseBaseBean) {
                                super.onNext(responseBaseBean);
                                if (onResult != null) {
                                    onResult.onSuccess();
                                }
                            }
                        });
            }else{
                Observable.create(new Observable.OnSubscribe<List<NovelEditModel>>() {
                    @Override
                    public void call(Subscriber<? super List<NovelEditModel>> subscriber) {
                        //上传该章节的所有本地历史
                        List<NovelEditModel> list = dbUtil.getListByChapterId(model.getNovel_id(), model.getChapter_id());
                        subscriber.onNext(list);

                    }
                }).compose(RxJavaHelper.<List<NovelEditModel>>observeOnMainThread())
                .subscribe(new BaseSubscriber<List<NovelEditModel>>(){
                    @Override
                    public void onNext(List<NovelEditModel> list) {
                        super.onNext(list);
                        uploadPartLocalData(list, new OnResult() {
                            @Override
                            public void onSuccess() {
                                if (onResult != null) {
                                    onResult.onSuccess();
                                }
                            }

                            @Override
                            public void onError(String msg) {
                                if (onResult != null) {
                                    onResult.onError("成功保存至本地");
                                }
                            }
                        });
                    }
                });
            }
        }
    }


    /**
     * 根据DBID删除数据
     * @param id
     */
    public void deleteByDBId(final long id) {
        Observable.create(new Observable.OnSubscribe<Boolean>() {
            @Override
            public void call(Subscriber<? super Boolean> subscriber) {
                dbUtil.deleteById(id);
            }
        }).compose(RxJavaHelper.<Boolean>observeOnMainThread())
        .subscribe(new BaseSubscriber<Boolean>(){
            @Override
            public void onNext(Boolean aBoolean) {
                super.onNext(aBoolean);
            }
        });
    }

    /**
     * 恢复备份数据
     * @param model
     * @param backupID
     */
    public void resetBackup(NovelEditModel model, long backupID,final OnResult onResult) {
        ApiClient.getInstance().getService().resetBackUp(formatData(model),backupID)
                .compose(RxJavaHelper.<ResponseBaseBean>observeOnMainThread())
                .subscribe(new BaseSubscriber<ResponseBaseBean>(){
                    @Override
                    public void onError(Throwable e) {
                        super.onError(e);
                        if (onResult != null) {
                            if (NetworkUtil.isNetworkUsable(WeMediaApplication.applicationContext)) {
                                onResult.onError("网络异常，请检查网络后再试");
                            }else{
                                onResult.onError("恢复失败，请重试");
                            }
                        }
                    }

                    @Override
                    public void onNext(ResponseBaseBean responseBaseBean) {
                        super.onNext(responseBaseBean);
                        if (onResult != null) {
                            if (responseBaseBean != null) {
                                if (TextUtils.isEmpty(responseBaseBean.getUser_msg())){
                                    onResult.onSuccess();
                                }else{
                                    onResult.onError(responseBaseBean.getUser_msg());
                                }
                            }else{
                                onResult.onError("恢复失败，请重试");
                            }

                        }
                    }
                });
    }


    private String formatData(NovelEditModel model) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("novel_id", model.getNovel_id());
        jsonObject.put("chapter_id", model.getChapter_id());
        jsonObject.put("title", model.getTitle());
        jsonObject.put("content", model.getContent());
        jsonObject.put("author_say", model.getAuthor_say());
        jsonObject.put("created_at", model.getCreated_at());
        jsonObject.put("flag", model.getFlag());
        return jsonObject.toJSONString();
    }





    private static final int UPLOAD_COUNT = 10;

    /**
     * 批量上传草稿
     */
    public void uploadAllData() {

        try {
            if (AccountService.getInstance().isLogin()) {
                final String uid = AccountService.getInstance().getUserUid();
                boolean alreadySwitch = DiaoBaoSharedPreferences.getSharedPreferencesValueToBoolean("novel_edit_already_switch"+uid, WeMediaApplication.applicationContext, false);
                if (alreadySwitch) {
                    if (dbUtil.hasLocalData(uid)) {
                        Observable.create(new Observable.OnSubscribe<List<NovelEditModel>>() {
                            @Override
                            public void call(Subscriber<? super List<NovelEditModel>> subscriber) {
                                //获取本地未同步的数据
                                List<NovelEditModel> list = dbUtil.getAllListByUid(uid);
                                subscriber.onNext(list);
                            }
                        }).compose(RxJavaHelper.<List<NovelEditModel>>observeOnMainThread())
                                .subscribe(new BaseSubscriber<List<NovelEditModel>>(){
                                    @Override
                                    public void onNext(List<NovelEditModel> list) {
                                        super.onNext(list);
                                        uploadPartLocalData(list,null);
                                    }
                                });
                    }
                }else{
                    dataSwitch(uid);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public NovelEditModel getLastLocalDataByChapterId(String novelId, String chapter_id) {
        List<NovelEditModel> list = dbUtil.getListByChapterId(novelId, chapter_id);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }


    private void uploadPartLocalData(final List<NovelEditModel> list,final OnResult onResult) {
        if (list != null && list.size() > 0) {
            int count = UPLOAD_COUNT;
            if (list.size() < UPLOAD_COUNT) {
                count = list.size();
            }

            JSONArray array = new JSONArray();
            for (int i = count-1; i >=0; i--) {
                NovelEditModel model = list.get(i);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("dbID", model.getId());
                jsonObject.put("novel_id", model.getNovel_id());
                jsonObject.put("chapter_id", model.getChapter_id());
                jsonObject.put("title", model.getTitle());
                jsonObject.put("content", model.getContent());
                jsonObject.put("author_say", model.getAuthor_say());
                jsonObject.put("created_at", model.getCreated_at());
                jsonObject.put("flag", model.getFlag());
                array.add(jsonObject);
                list.remove(i);
            }

            //将以上获取的数据上传到服务器
            ApiClient.getInstance().getService().uploadMyAllBackUp(array.toJSONString())
                    .map(new Func1<NovelUploadBackupGsonBean, NovelUploadBackupGsonBean>() {
                        @Override
                        public NovelUploadBackupGsonBean call(NovelUploadBackupGsonBean novelUploadBackupGsonBean) {
                            if (novelUploadBackupGsonBean != null && novelUploadBackupGsonBean.getData() != null &&
                                    novelUploadBackupGsonBean.getData().getSuccessList() != null && novelUploadBackupGsonBean.getData().getSuccessList().size() > 0) {
                                //更新本地数据状态
                                dbUtil.deletePartData(novelUploadBackupGsonBean.getData().getSuccessList());
                            }
                            return novelUploadBackupGsonBean;
                        }
                    })
                    .compose(RxJavaHelper.<NovelUploadBackupGsonBean>observeOnMainThread())
                    .subscribe(new BaseSubscriber<NovelUploadBackupGsonBean>(){
                        @Override
                        public void onError(Throwable e) {
                            super.onError(e);
                            if (onResult != null) {
                                onResult.onError("");
                            }
                        }

                        @Override
                        public void onNext(NovelUploadBackupGsonBean responseBaseBean) {
                            super.onNext(responseBaseBean);
                            if (onResult != null) {
                                onResult.onSuccess();
                            }else{
                                if (list != null && list.size() == 0) {
                                    //网络重新连接等情况下同步成功后需要刷新UI
                                    EventBusRefreshData event = new EventBusRefreshData();
                                    event.setTag(EventBusRefreshData.tag);
                                    event.setError(false);
                                    EventBus.getDefault().post(event);
                                }
                            }
                            uploadPartLocalData(list,null);
                        }
                    });
        }
    }


    public List<NovelEditModel> getCreatedList(String novelId) {
        return dbUtil.getListByChapterId(novelId,"-1");
    }

    /**
     * 保存临时数据
     * @param model
     */
    public void saveTempData(final NovelEditModel model, final PublicInterface.OnLongResult onLongResult) {
        Observable.create(new Observable.OnSubscribe<Long>() {
                    @Override
                    public void call(Subscriber<? super Long> subscriber) {
                        long id = dbUtil.insertOrUpdateTempData(model);
                        subscriber.onNext(id);
                    }
                }).compose(RxJavaHelper.<Long>observeOnMainThread())
                .subscribe(new BaseSubscriber<Long>(){
                    @Override
                    public void onNext(Long l) {
                        super.onNext(l);
                        if (onLongResult != null) {
                            onLongResult.onResult(l);
                        }
                    }
                });
    }



    public void getNovelIdMap(final String novelID, final PublicInterface.OnHashMapResult onHashMapResult) {
        Observable.create(new Observable.OnSubscribe<HashMap>() {
            @Override
            public void call(Subscriber<? super HashMap> subscriber) {
                HashMap map = dbUtil.getNovelIDMap(novelID);
                subscriber.onNext(map);
            }
        }).compose(RxJavaHelper.<HashMap>observeOnMainThread())
                .subscribe(new BaseSubscriber<HashMap>(){
                    @Override
                    public void onNext(HashMap map) {
                        super.onNext(map);
                        if (onHashMapResult != null) {
                            onHashMapResult.onResult(map);
                        }
                    }
                });
    }


    /**
     * 将旧版本的数据转换成新版本的格式
     */
    public void dataSwitch(final String uid) {
        //获取用户的小说ID列表
        ApiClient.getInstance().getService().getAllNovelsByUid()
                .map(new Func1<NovelChaptersGsonBean, Boolean>() {
                    @Override
                    public Boolean call(NovelChaptersGsonBean bean) {
                        if (bean!=null && bean.getData()!=null &&
                                bean.getData().getList()!=null){
                            if (bean.getData().getList().size()>0){
                                //通过小说ID获取所有的本地记录并将
                                List<NovelEditModel> list = getEditNovelDataFromSPByIds(bean.getData().getList(),uid);
                                dbUtil.insertAllData(list);
                            }
                            return true;
                        }
                        return false;
                    }
                })
                .compose(RxJavaHelper.<Boolean>observeOnMainThread())
                .subscribe(new BaseSubscriber<Boolean>(){
                    @Override
                    public void onNext(Boolean b) {
                        super.onNext(b);
                        if (b){
                            DiaoBaoSharedPreferences.setSharedPreferencesValueToBoolean("novel_edit_already_switch"+uid,true,WeMediaApplication.applicationContext);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        super.onError(e);
                    }
                });
    }




    /**
     * 获取sp中的旧数据
     * @param list
     * @return
     */
    private List<NovelEditModel> getEditNovelDataFromSPByIds(List<NovelChapterIDBean.NovelItem> list,String uid) {
        SharedPreferences createSP = SharedPreferenceUtil.createNovel(WeMediaApplication.applicationContext);
        SharedPreferences draftsSP = SharedPreferenceUtil.novelDrafts(WeMediaApplication.applicationContext);
        SharedPreferences sentSP = SharedPreferenceUtil.novelSend(WeMediaApplication.applicationContext);
        List<NovelEditModel> formatList = new ArrayList<>();
        for (NovelChapterIDBean.NovelItem item: list) {
            String novelId = String.valueOf(item.getNovelId());
            if (TextUtils.isEmpty(novelId)) {
                continue;
            }
            //新建章节备份数据转换
            NovelEditModel node = new NovelEditModel();
            node.setNovel_id(novelId);
            node.setChapter_id("-1");
            node.setFlag(NOVEL_CREATE);
            node.setTitle(createSP.getString(Constant.NovelCreate.TITLE+novelId,""));
            node.setContent(createSP.getString(Constant.NovelCreate.CONTENT+novelId,""));
            node.setAuthor_say(createSP.getString(Constant.NovelCreate.AUTHORSAY+novelId,""));
            node.setCreated_at(System.currentTimeMillis()/1000);
            node.setUid(uid);
            formatList.add(node);
            //草稿章节备份数据转换
            List<Integer> draftIds = item.getDraftIds();
            if (draftIds != null && draftIds.size() > 0) {
                for (Integer id:draftIds) {
                    if (id <= 0) {
                        continue;
                    }
                    NovelEditModel model = new NovelEditModel();
                    model.setNovel_id(novelId);
                    model.setChapter_id(String.valueOf(id));
                    model.setFlag(NOVEL_DRAFTS);
                    model.setTitle(draftsSP.getString(Constant.NovelDrafs.TITLE+id,""));
                    model.setContent(draftsSP.getString(Constant.NovelDrafs.CONTENT+id,""));
                    model.setAuthor_say(draftsSP.getString(Constant.NovelDrafs.AUTHORSAY+id,""));
                    model.setCreated_at(System.currentTimeMillis()/1000);
                    model.setUid(uid);
                    formatList.add(model);
                }
            }

            //已发布章节备份数据转换
            List<Integer> formalIds = item.getFormalIds();
            if (formalIds != null && formalIds.size() > 0) {
                for (Integer id:formalIds) {
                    if (id <= 0) {
                        continue;
                    }
                    NovelEditModel model = new NovelEditModel();
                    model.setNovel_id(novelId);
                    model.setChapter_id(String.valueOf(id));
                    model.setFlag(NOVEL_SECTION);
                    model.setTitle(sentSP.getString(Constant.NovelSend.TITLE+id,""));
                    model.setContent(sentSP.getString(Constant.NovelSend.CONTENT+id,""));
                    model.setAuthor_say(sentSP.getString(Constant.NovelSend.AUTHORSAY+id,""));
                    model.setCreated_at(System.currentTimeMillis()/1000);
                    model.setUid(uid);
                    formatList.add(model);
                }
            }

        }
        return formatList;
    }

}
